using System.Diagnostics;
using DimensionsHelper.LanguageService.Symbols;
using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService;

public class AnalysisIfStatement : AnalysisStatement
{
    internal AnalysisIfStatement(
        IfStatement syntaxNode,
        AnalysisExpression? condition,
        AnalysisBlock body,
        AnalysisStatement? alternative,
        AnalysisNode? parent) : 
        base(AnalysisBoundKinds.IfStatement, syntaxNode, parent)
    {
        Syntax = syntaxNode;
        Condition = condition;
        Body = body;
        Alternative = alternative;
    }

    public override IfStatement Syntax { get; }

    /// <summary>
    ///     条件语句。
    /// </summary>
    public AnalysisExpression? Condition { get; }

    /// <summary>
    ///     条件体内的语句
    /// </summary>
    public AnalysisBlock Body { get; }

    /// <summary>
    ///     后续分支语句。
    /// </summary>
    public AnalysisStatement? Alternative { get; private set; }


    public override int ChildrenCount => Alternative == null ? 2 : 3;


    public override IEnumerable<AnalysisNode> GetChildren()
    {
        if (Alternative == null)
        {
            return Condition == null ? [Body] : [Condition, Body];
        }

        return Condition == null ? [Body, Alternative] : [Condition, Body, Alternative];
    }


    internal override void AddChild(AnalysisNode child)
    {
        if (child is AnalysisIfStatement alternative)
        {
            Debug.Assert(Alternative == null, "Already have an alternative.");
            alternative.Parent = this;
            Alternative = alternative;
        }
        else
        {
            throw new NotSupportedException("Only alternatives can be added to this analysis statement.");
        }
    }
}

public static partial class AnalysisNodeFactory
{
    /// <summary>
    /// 创建一个条件语句
    /// </summary>
    /// <param name="syntaxNode">原始语法节点</param>
    /// <param name="condition">条件语句，如果是<see langword="null"/>，表示是Else语句</param>
    /// <param name="body">语法体</param>
    /// <param name="alternative">下一个条件语句</param>
    /// <param name="parent">父节点，可以忽略</param>
    /// <param name="withSymbol">语法节点所在的With语句上下文类型符号</param>
    public static AnalysisIfStatement IfStatement(IfStatement syntaxNode,
        AnalysisExpression? condition,
        AnalysisBlock body,
        AnalysisStatement? alternative,
        AnalysisNode? parent,
        ITypeSymbol? withSymbol)
    {
        return new AnalysisIfStatement(syntaxNode, condition, body, alternative, parent)
            .WithContainingWithSymbol(withSymbol);
    }
}